package com.qigao.mall.channel.weichat;

import com.alibaba.fastjson.JSONObject;
import com.qigao.mall.channel.ChannelCore;
import com.qigao.mall.commons.dto.MerChannelDto;
import com.qigao.mall.commons.enums.ChannelActionEnum;
import com.qigao.mall.commons.enums.ChannelCodeEnum;
import com.qigao.mall.commons.enums.ChannelInfoEnum;
import com.qigao.mall.commons.enums.PayProductEnum;
import com.qigao.mall.commons.param.ChannelReqParam;
import com.qigao.mall.commons.param.ChannelRespParam;
import com.qigao.mall.commons.utils.PayUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/***
 * 微信小程序订单请求
 */
@Service
public class WeiChatJsapiPay extends AbstractWeichatTrade implements ChannelCore {

    private static Logger logger= LoggerFactory.getLogger(WeiChatJsapiPay.class);

    @Override
    public boolean isSupport(PayProductEnum payProductEnum, ChannelActionEnum channelActionEnum, ChannelInfoEnum channelInfoEnum) {
        return ChannelActionEnum.CREATE_ORDER.equals(channelActionEnum) && PayProductEnum.WEICHAT_SMALL_APP.equals(payProductEnum);
    }


    @Override
    protected String getSelfReqUrl() {
        return channelConstant.getWeichatOrderUrl();
    }

    @Override
    public Map buildSelfReqParam(MerChannelDto merChannelDto, ChannelReqParam channelReqParam) {
        Map reqParam=new ConcurrentHashMap<String,String>();
        JSONObject reqContent= JSONObject.parseObject(channelReqParam.getReqContent());
        reqParam.put("out_trade_no", merChannelDto.getInnerSeqNo());
        reqParam.put("device_info", "WEB");
        reqParam.put("fee_type", "CNY");
        reqParam.put("body",reqContent.getString("goodsName"));
        reqParam.put("openid",channelReqParam.getOpenId());//
        reqParam.put("total_fee", reqContent.getString("payAmtFen"));//订单总金额，单位为分，详见支付金额
        reqParam.put("spbill_create_ip",channelReqParam.getTermIp());//必须传正确的用户端IP,支持ipv4、ipv6格式，获取方式详见获取用户ip指引
        reqParam.put("time_start", reqContent.getString("startTimeStr"));// 交易起始时间  否 订单生成时间，格式为yyyyMMddHHmmss，如2009年12月25日9点10分10秒表示为20091225091010
        reqParam.put("time_expire", reqContent.getString("endTimeStr"));//交易结束时间  否 订单失效时间，格式为yyyyMMddHHmmss，如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则
        //reqParam.put("goods_tag", " ");//商品标记，否 代金券或立减优惠功能的参数，说明详见代金券或立减优惠
        reqParam.put("notify_url",channelConstant.getWeichatNotifyUrl());
        reqParam.put("trade_type","JSAPI");//JSAPI--JSAPI支付（或小程序支付）、NATIVE--Native支付、APP--app支付，MWEB--H5支付，不同trade_type决定了调起支付的方式，请根据支付产品正确上传 MICROPAY--付款码支付，付款码支付有单独的支付接口，所以接口不需要上传，该字段在对账单中会出现
        reqParam.put("openid", channelReqParam.getOpenId());//trade_type=JSAPI，此参数必传，用户在商户appid下的唯一标识
        reqParam.put("profit_sharing","Y");//是否允许分账 todo 通过参数调整
        return reqParam;
    }

    @Override
    protected ChannelRespParam buildSelfRespData(Map respMap, MerChannelDto merChannelDto) {
        String prepay_id= (String) respMap.get("prepay_id");   //prepay_id  微信生成的预支付会话标识，用于后续接口调用中使用，该值有效期为2小时
        String appId=(String) respMap.get("appid");
        String timeStamp= PayUtil.createTimestamp();
        String nonceStr=PayUtil.getRandomString(32);
        String packageData="prepay_id="+prepay_id;
        Map respDataMap=new HashMap();
        respDataMap.put("appId",appId);
        respDataMap.put("timeStamp",timeStamp);
        respDataMap.put("nonceStr",nonceStr);
        respDataMap.put("package",packageData);
        respDataMap.put("signType",merChannelDto.getSignType());
        String paySign=PayUtil.createSign(respDataMap,merChannelDto.getSignType(),merChannelDto.getMd5Key());
        respDataMap.put("sign",paySign);
        String retStr=JSONObject.toJSONString(respDataMap);
        logger.info("返回给小程序继续调用的参数:{}",retStr);
        ChannelRespParam channelRespParam=new ChannelRespParam();
        channelRespParam.setRespCode(ChannelCodeEnum.SUCCESS.getCode());
        channelRespParam.setRespMsg(ChannelCodeEnum.SUCCESS.getName());
        channelRespParam.setRespContent(retStr);
        return  channelRespParam;
    }

}
